package com.atqar.poll;

import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService threadPool = new ThreadPoolExecutor(

        /*      核心线程数复杂运算,耗用cpu资源的建议合理的线程数值是 N(CPU)数 + 1。=
                等待时间长参考值可以是 N(CPU) 核数 * 2。*/
                Runtime.getRuntime().availableProcessors(),

                //maximumPoolSize：线程池中能够容纳同时执行的最大线程数，此值必须大于等于1
                Runtime.getRuntime().availableProcessors() + 1,
                //keepAliveTime：多余的空闲线程的存活时间和时间单位
                1L,
                TimeUnit.SECONDS,
                //等待队列
                new ArrayBlockingQueue<>(3),

                //创建线程池工厂一般默认即可
                Executors.defaultThreadFactory(),

             /*   拒绝策略:
                AbortPolicy(默认)：直接抛出RejectedExecutionException异常阻止系统正常运行
                CallerRunsPolicy：“调用者运行”一种调节机制，该策略既不会抛弃任务，也不会抛出异常，而是将某些任务回退到调用者，从而降低新任务的流量。
                DiscardPolicy：该策略默默地丢弃无法处理的任务，不予任何处理也不抛出异常。如果允许任务丢失，这是最好的一种策略。
                DiscardOldestPolicy：抛弃队列中等待最久的任务，然后把当前任务加人队列中尝试再次提交当前任务。*/
                new ThreadPoolExecutor.DiscardOldestPolicy());

        try {
            for (int i = 1; i <= 10; i++) { //5个顾客（请求线程）来办理业务
                int finalI = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"\t"+"为："+ finalI +"\t客户办理业务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }

    }

    private static void defaultPool() {

        //不能用这几种方式创建线程池要用executors允许请求队列长度为Integer.max.value可能会堆积大量的请求导致oom  我们用threadpoolexecutor创建线程池避免资源耗尽
        ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池固定数
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();//一池1线程
        //ExecutorService threadPool = Executors.newCachedThreadPool();//一池N线程

        try {
            for (int i = 0; i < 10; i++) { //20个顾客（请求线程）来办理业务
                int finalI = i;
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"\t"+"为："+ finalI +"\t客户办理业务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
}
